iT邦幫忙

2023 iThome 鐵人賽

DAY 26
0

昨天我們完成了,從Linebot收到檔案,並且上傳到Google Drive上的指定資料夾。

但是目前指定資料夾的ID是寫死的,我們也不可能每次要指定資料夾都去查一次FolderID,然後讓使用者手動輸入ID。加上目前顯示資料夾的方式也是直接用文字印出的,所以我們今天來刻個Flex Message,讓我們的介面美觀一點,並且一切操作都能透過按鈕完成。

首先,我們到Line官方提供的Flex Message Simulator,建立一個carousel,簡單拉出想像中的樣子,目前希望的設定大概如下:

  • carousel下的每一個bubble都代表一個資料夾
  • 一開始可以選擇顯示”根目錄”or”與我共用”下的資料夾
  • 一個資料夾下可能有其他子資料夾,旁邊要有按鈕可以進入該資料夾,讓linebot依照相同的carousel格式顯示該資料夾下的內容
  • Folder Name下會顯示當前的目錄路徑
  • 顯示所有檔案名稱,並統計有多少檔案。(這邊都先不考慮檔案的顯示上限)
  • 最下面有一個按鈕,可以設定當前的資料夾為我們默認的上傳路徑。

大概拉出下面這樣子
https://ithelp.ithome.com.tw/upload/images/20231011/20115990ITRHLZyZ3q.png

接著我們透過網站直接將其導出成JSON,我們先放一個bubble就好。

{
  "type": "carousel",
  "contents": [
    {
      "type": "bubble",
      "body": {
        "type": "box",
        "layout": "vertical",
        "contents": [
          {
            "type": "text",
            "text": "FOLDER",
            "weight": "bold",
            "color": "#1DB446",
            "size": "sm"
          },
          {
            "type": "text",
            "text": "Folder Name",
            "weight": "bold",
            "size": "xxl",
            "margin": "md"
          },
          {
            "type": "text",
            "text": "/path/to/floder",
            "size": "xs",
            "color": "#aaaaaa",
            "wrap": true
          },
          {
            "type": "separator",
            "margin": "xxl"
          },
          {
            "type": "box",
            "layout": "vertical",
            "margin": "xxl",
            "spacing": "sm",
            "contents": [
              {
                "type": "box",
                "layout": "horizontal",
                "contents": [
                  {
                    "type": "text",
                    "text": "Folder1",
                    "size": "sm",
                    "color": "#555555",
                    "decoration": "underline",
                    "maxLines": 25,
                    "align": "start",
                    "margin": "none",
                    "gravity": "center",
                    "flex": 0
                  },
                  {
                    "type": "filler"
                  },
                  {
                    "type": "button",
                    "action": {
                      "type": "postback",
                      "label": "進入資料夾",
                      "data": "hello",
                      "displayText": "進入Folder1"
                    },
                    "style": "link",
                    "height": "sm",
                    "gravity": "center",
                    "flex": 0,
                    "adjustMode": "shrink-to-fit"
                  }
                ]
              },
              {
                "type": "box",
                "layout": "horizontal",
                "contents": [
                  {
                    "type": "text",
                    "text": "Folder2",
                    "size": "sm",
                    "color": "#555555",
                    "decoration": "underline",
                    "maxLines": 25,
                    "align": "start",
                    "margin": "none",
                    "gravity": "center",
                    "flex": 0
                  },
                  {
                    "type": "filler"
                  },
                  {
                    "type": "button",
                    "action": {
                      "type": "postback",
                      "label": "進入資料夾",
                      "data": "hello",
                      "displayText": "進入Folder2"
                    },
                    "style": "link",
                    "height": "sm",
                    "gravity": "center",
                    "flex": 0,
                    "adjustMode": "shrink-to-fit"
                  }
                ]
              },
              {
                "type": "separator",
                "margin": "xxl"
              },
              {
                "type": "box",
                "layout": "horizontal",
                "margin": "xxl",
                "contents": [
                  {
                    "type": "text",
                    "text": "Total Files",
                    "size": "sm",
                    "color": "#555555",
                    "flex": 0
                  },
                  {
                    "type": "text",
                    "text": "3",
                    "size": "sm",
                    "color": "#111111",
                    "align": "end"
                  }
                ]
              },
              {
                "type": "box",
                "layout": "horizontal",
                "contents": [
                  {
                    "type": "text",
                    "text": "FILE1",
                    "size": "sm",
                    "color": "#555555"
                  }
                ]
              },
              {
                "type": "box",
                "layout": "horizontal",
                "contents": [
                  {
                    "type": "text",
                    "text": "FILE2",
                    "size": "sm",
                    "color": "#555555"
                  }
                ]
              },
              {
                "type": "box",
                "layout": "horizontal",
                "contents": [
                  {
                    "type": "text",
                    "text": "FILE3",
                    "size": "sm",
                    "color": "#555555"
                  }
                ]
              }
            ]
          },
          {
            "type": "separator",
            "margin": "xxl"
          },
          {
            "type": "box",
            "layout": "horizontal",
            "margin": "md",
            "contents": [
              {
                "type": "button",
                "action": {
                  "type": "postback",
                  "label": "設為上傳資料夾",
                  "data": "folderid"
                },
                "scaling": true,
                "style": "primary",
                "adjustMode": "shrink-to-fit"
              }
            ]
          }
        ]
      },
      "styles": {
        "footer": {
          "separator": true
        }
      }
    },
    {
      "type": "bubble",
      "body": {
        "type": "box",
        "layout": "vertical",
        "contents": [
          {
            "type": "text",
            "text": "FOLDER",
            "weight": "bold",
            "color": "#1DB446",
            "size": "sm"
          },
          {
            "type": "text",
            "text": "Folder Name",
            "weight": "bold",
            "size": "xxl",
            "margin": "md"
          },
          {
            "type": "text",
            "text": "/path/to/floder",
            "size": "xs",
            "color": "#aaaaaa",
            "wrap": true
          },
          {
            "type": "separator",
            "margin": "xxl"
          },
          {
            "type": "box",
            "layout": "vertical",
            "margin": "xxl",
            "spacing": "sm",
            "contents": [
              {
                "type": "box",
                "layout": "horizontal",
                "contents": [
                  {
                    "type": "text",
                    "text": "Folder1",
                    "size": "sm",
                    "color": "#555555",
                    "decoration": "underline",
                    "maxLines": 25,
                    "align": "start",
                    "margin": "none",
                    "gravity": "center",
                    "flex": 0
                  },
                  {
                    "type": "filler"
                  },
                  {
                    "type": "button",
                    "action": {
                      "type": "postback",
                      "label": "進入資料夾",
                      "data": "hello",
                      "displayText": "進入Folder1"
                    },
                    "style": "link",
                    "height": "sm",
                    "gravity": "center",
                    "flex": 0,
                    "adjustMode": "shrink-to-fit"
                  }
                ]
              },
              {
                "type": "box",
                "layout": "horizontal",
                "contents": [
                  {
                    "type": "text",
                    "text": "Folder2",
                    "size": "sm",
                    "color": "#555555",
                    "decoration": "underline",
                    "maxLines": 25,
                    "align": "start",
                    "margin": "none",
                    "gravity": "center",
                    "flex": 0
                  },
                  {
                    "type": "filler"
                  },
                  {
                    "type": "button",
                    "action": {
                      "type": "postback",
                      "label": "進入資料夾",
                      "data": "hello",
                      "displayText": "進入Folder2"
                    },
                    "style": "link",
                    "height": "sm",
                    "gravity": "center",
                    "flex": 0,
                    "adjustMode": "shrink-to-fit"
                  }
                ]
              },
              {
                "type": "separator",
                "margin": "xxl"
              },
              {
                "type": "box",
                "layout": "horizontal",
                "margin": "xxl",
                "contents": [
                  {
                    "type": "text",
                    "text": "Total Files",
                    "size": "sm",
                    "color": "#555555",
                    "flex": 0
                  },
                  {
                    "type": "text",
                    "text": "3",
                    "size": "sm",
                    "color": "#111111",
                    "align": "end"
                  }
                ]
              },
              {
                "type": "box",
                "layout": "horizontal",
                "contents": [
                  {
                    "type": "text",
                    "text": "FILE1",
                    "size": "sm",
                    "color": "#555555"
                  }
                ]
              },
              {
                "type": "box",
                "layout": "horizontal",
                "contents": [
                  {
                    "type": "text",
                    "text": "FILE2",
                    "size": "sm",
                    "color": "#555555"
                  }
                ]
              },
              {
                "type": "box",
                "layout": "horizontal",
                "contents": [
                  {
                    "type": "text",
                    "text": "FILE3",
                    "size": "sm",
                    "color": "#555555"
                  }
                ]
              }
            ]
          },
          {
            "type": "separator",
            "margin": "xxl"
          },
          {
            "type": "box",
            "layout": "horizontal",
            "margin": "md",
            "contents": [
              {
                "type": "button",
                "action": {
                  "type": "postback",
                  "label": "設為上傳資料夾",
                  "data": "folderid"
                },
                "scaling": true,
                "style": "primary",
                "adjustMode": "shrink-to-fit"
              }
            ]
          }
        ]
      },
      "styles": {
        "footer": {
          "separator": true
        }
      }
    }
  ]
}

下一步,我們到Callback加入新的條件來回傳我們建立的carousel。
接著最痛苦的時間來了,對照著上面的JSON,我們要用Go組出對應的結構,基本打上關鍵字VsCode會自動跳出對應的結構給你選,所以對著JSON打就好。
比較要注意的是有些字段都是要求接收指向Int的指標,像是Flex之類的,這時候可以直接用linebot.IntPtr()來回傳指標。
下面有一些地方有IT邦有跑版,畢竟一堆縮排,複製到VSCode會比較清楚。

// internal\router\api\v1\callback.go
if message.Text == "flex carousel" {
    contents := &linebot.CarouselContainer{
        Type: linebot.FlexContainerTypeCarousel,
        Contents: []*linebot.BubbleContainer{
            {
                Type: linebot.FlexContainerTypeBubble,
                Body: &linebot.BoxComponent{
                    Type:   linebot.FlexComponentTypeBox,
                    Layout: linebot.FlexBoxLayoutTypeVertical,
                    Contents: []linebot.FlexComponent{
                        &linebot.TextComponent{
                            Type:   linebot.FlexComponentTypeText,
                            Text:   "FOLDER",
                            Weight: linebot.FlexTextWeightTypeBold,
                            Color:  "#1DB446",
                            Size:   linebot.FlexTextSizeTypeSm,
                        },
                        &linebot.TextComponent{
                            Type:   linebot.FlexComponentTypeText,
                            Text:   "Folder Name",
                            Weight: linebot.FlexTextWeightTypeBold,
                            Size:   linebot.FlexTextSizeTypeXxl,
                            Margin: linebot.FlexComponentMarginTypeMd,
                        },
                        &linebot.TextComponent{
                            Type:  linebot.FlexComponentTypeText,
                            Text:  "/path/to/floder",
                            Size:  linebot.FlexTextSizeTypeXs,
                            Color: "#aaaaaa",
                            Wrap:  true,
                        },
                        &linebot.SeparatorComponent{
                            Type:   linebot.FlexComponentTypeSeparator,
                            Margin: linebot.FlexComponentMarginTypeXxl,
                        },
                        &linebot.BoxComponent{
                            Type:    linebot.FlexComponentTypeBox,
                            Layout:  linebot.FlexBoxLayoutTypeVertical,
                            Margin:  linebot.FlexComponentMarginTypeXxl,
                            Spacing: linebot.FlexComponentSpacingTypeSm,
                            Contents: []linebot.FlexComponent{
                                &linebot.BoxComponent{
                                    Type:   linebot.FlexComponentTypeBox,
                                    Layout: linebot.FlexBoxLayoutTypeHorizontal,
                                    Contents: []linebot.FlexComponent{
                                        &linebot.TextComponent{
                                            Type:       linebot.FlexComponentTypeText,
                                            Text:       "Folder1",
                                            Size:       linebot.FlexTextSizeTypeSm,
                                            Color:      "#555555",
                                            Decoration: linebot.FlexTextDecorationTypeUnderline,
                                            MaxLines:   linebot.IntPtr(25),
                                            Align:      linebot.FlexComponentAlignTypeStart,
                                            Margin:     linebot.FlexComponentMarginTypeNone,
                                            Gravity:    linebot.FlexComponentGravityTypeCenter,
                                            Flex:       linebot.IntPtr(0),
                                        },
                                        &linebot.FillerComponent{
                                            Type: linebot.FlexComponentTypeFiller,
                                        },
                                        &linebot.ButtonComponent{
                                            Type: linebot.FlexComponentTypeButton,
                                            Action: &linebot.PostbackAction{
                                                Label:       "進入資料夾",
                                                Data:        "folderid1",
                                                DisplayText: "進入Folder1",
                                            },
                                            Style:      linebot.FlexButtonStyleTypeLink,
                                            Height:     linebot.FlexButtonHeightTypeSm,
                                            Gravity:    linebot.FlexComponentGravityTypeCenter,
                                            Flex:       linebot.IntPtr(0),
                                            AdjustMode: linebot.FlexComponentAdjustModeTypeShrinkToFit,
                                        },
                                    },
                                },
                                &linebot.BoxComponent{
                                    Type:   linebot.FlexComponentTypeBox,
                                    Layout: linebot.FlexBoxLayoutTypeHorizontal,
                                    Contents: []linebot.FlexComponent{
                                        &linebot.TextComponent{
                                            Type:       linebot.FlexComponentTypeText,
                                            Text:       "Folder2",
                                            Size:       linebot.FlexTextSizeTypeSm,
                                            Color:      "#555555",
                                            Decoration: linebot.FlexTextDecorationTypeUnderline,
                                            MaxLines:   linebot.IntPtr(25),
                                            Align:      linebot.FlexComponentAlignTypeStart,
                                            Margin:     linebot.FlexComponentMarginTypeNone,
                                            Gravity:    linebot.FlexComponentGravityTypeCenter,
                                            Flex:       linebot.IntPtr(0),
                                        },
                                        &linebot.FillerComponent{
                                            Type: linebot.FlexComponentTypeFiller,
                                        },
                                        &linebot.ButtonComponent{
                                            Type: linebot.FlexComponentTypeButton,
                                            Action: &linebot.PostbackAction{
                                                Label:       "進入資料夾",
                                                Data:        "folderid2",
                                                DisplayText: "進入Folder2",
                                            },
                                            Style:      linebot.FlexButtonStyleTypeLink,
                                            Height:     linebot.FlexButtonHeightTypeSm,
                                            Gravity:    linebot.FlexComponentGravityTypeCenter,
                                            Flex:       linebot.IntPtr(0),
                                            AdjustMode: linebot.FlexComponentAdjustModeTypeShrinkToFit,
                                        },
                                    },
                                },
                            },
                        },
                        // Separator
                        &linebot.SeparatorComponent{
                            Margin: linebot.FlexComponentMarginTypeXxl,
                        },
                        // Files
                        &linebot.BoxComponent{
                            Type:   linebot.FlexComponentTypeBox,
                            Layout: linebot.FlexBoxLayoutTypeHorizontal,
                            Margin: linebot.FlexComponentMarginTypeXxl,
                            Contents: []linebot.FlexComponent{
                                &linebot.TextComponent{
                                    Type:  linebot.FlexComponentTypeText,
                                    Text:  "Total Files",
                                    Size:  linebot.FlexTextSizeTypeSm,
                                    Color: "#555555",
                                    Flex:  linebot.IntPtr(0),
                                },
                                &linebot.TextComponent{
                                    Type:  linebot.FlexComponentTypeText,
                                    Text:  "3",
                                    Size:  linebot.FlexTextSizeTypeSm,
                                    Color: "#111111",
                                    Align: linebot.FlexComponentAlignTypeEnd,
                                },
                            },
                        },
                        &linebot.BoxComponent{
                            Type:   linebot.FlexComponentTypeBox,
                            Layout: linebot.FlexBoxLayoutTypeHorizontal,
                            Contents: []linebot.FlexComponent{
                                &linebot.TextComponent{
                                    Type:  linebot.FlexComponentTypeText,
                                    Text:  "FILE1",
                                    Size:  linebot.FlexTextSizeTypeSm,
                                    Color: "#555555",
                                },
                            },
                        },
                        &linebot.BoxComponent{
                            Type:   linebot.FlexComponentTypeBox,
                            Layout: linebot.FlexBoxLayoutTypeHorizontal,
                            Contents: []linebot.FlexComponent{
                                &linebot.TextComponent{
                                    Type:  linebot.FlexComponentTypeText,
                                    Text:  "FILE2",
                                    Size:  linebot.FlexTextSizeTypeSm,
                                    Color: "#555555",
                                },
                            },
                        },
                        &linebot.BoxComponent{
                            Type:   linebot.FlexComponentTypeBox,
                            Layout: linebot.FlexBoxLayoutTypeHorizontal,
                            Contents: []linebot.FlexComponent{
                                &linebot.TextComponent{
                                    Type:  linebot.FlexComponentTypeText,
                                    Text:  "FILE3",
                                    Size:  linebot.FlexTextSizeTypeSm,
                                    Color: "#555555",
                                },
                            },
                        },
                        // Separator
                        &linebot.SeparatorComponent{
                            Margin: linebot.FlexComponentMarginTypeXxl,
                        },
                        // Button
                        &linebot.BoxComponent{
                            Type:   linebot.FlexComponentTypeBox,
                            Layout: linebot.FlexBoxLayoutTypeHorizontal,
                            Margin: linebot.FlexComponentMarginTypeMd,
                            Contents: []linebot.FlexComponent{
                                &linebot.ButtonComponent{
                                    Type: linebot.FlexComponentTypeButton,
                                    Action: &linebot.PostbackAction{
                                        Label:       "設為上傳資料夾",
                                        Data:        "folderid",
                                        DisplayText: "設為上傳資料夾",
                                    },
                                    Style:      linebot.FlexButtonStyleTypePrimary,
                                    AdjustMode: linebot.FlexComponentAdjustModeTypeShrinkToFit,
                                },
                            },
                        },
                    },
                },
                Styles: &linebot.BubbleStyle{
                    Footer: &linebot.BlockStyle{
                        Separator: true,
                    },
                },
            },
        },
    }
    if _, err := app.LineBotClient.ReplyMessage(
        event.ReplyToken,
        linebot.NewFlexMessage("Flex message alt text", contents),
    ).Do(); err != nil {
        log.Println(err)
        return
    }
}

組完眼睛真的要花了,最後到Linebot上測試一下,可以看到組出來的效果應該是跟我們拉的一致 (如果沒有眼花的話XD) ,那我們今天就先到這兒,明天見~
https://ithelp.ithome.com.tw/upload/images/20231011/201159903JVfLhLtho.png


上一篇
D25 Drive Service - 上傳檔案02
下一篇
Day27 用Go動態組合Flex Message 01
系列文
Golang LineBot X GoogleDrive:LINE有各種限制!? 那就丟上Drive吧!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言